<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2023-06-24 20:38:41
// |@----------------------------------------------------------------------
// |@LastEditTime : 2023-11-28 23:35:47
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : User.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2023 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------
namespace app\setting\logic;

use think\admin\extend\CodeExtend;
use think\admin\Logic;

/**
 * 用户管理类，用于实现用户相关的业务逻辑操作。
 */
class User extends Logic
{
    /**
     * 获取用户列表及所属用户信息
     * @param array $data 查询条件
     * @return array 用户列表及相关用户信息数组
     */
    public function getList(array $data): array
    {
        // 构建查询条件
        $where = [];
        if (!empty($data['name'])) {
            $where[] = ['name|username', 'like', '%' . $data['name'] . '%'];
        }
        if (!empty($data['dept_id'])) {
            $where[] = ['dept_id', '=', $data['dept_id']];
        }
        if (empty($where)) {
            $where[] = ['id', '>', 0];
        }

        // 构建分页参数
        $page = $data['page'] ?? 1;
        $pageSize = $data['pageSize'] ?? 20;
        // 使用关联模型一次性获取所有用户及其所属用户信息
        $users = $this->modelSystemUser->with('roles')->where($where)->order(['id' => 'desc'])->paginate(['list_rows' => $pageSize, 'page' => $page]);
        // 遍历查询结果，将关联查询出来的多个用户名拼接成一个字符串，并存放在一个新的role_name字段中
        foreach ($users as &$user) {
            // role_list 转为数组格式
            $user->role_list = json_decode($user->role_list) ?? [];
            $user->role_names = $this->logicRole->getRolesName($user->role_list);
            // 防止密码盐暴露，对密码盐进行MD5加密
            $user->salt = CodeExtend::md5ShaEncrypt($user->salt);
        }

        return $this->json(SUCCESS, lang('user.get_user_list_success'), $users->toArray());
    }

    /**
     * 保存用户信息
     * @param $data array 用户信息数组
     * @return mixed 返回保存结果和用户信息
     */
    public function saveUser(array $data)
    {
        return $this->tryCatch(function() use ($data) {
            // 处理用户列表
            $data['role_list'] = isset($data['role_list']) ? json_encode($data['role_list']) : '[]';
            // 处理创建时间，如果没有传入则使用当前时间
            $data['create_at'] = $data['create_at'] ?? date('Y-m-d H:i:s', time());
            try {
                if (!empty($data['id'])) {
                    // 如果传入的 $data 中有 id ，则执行更新操作
                    $this->modelSystemUser->updateById($data['id'], $data);
                    // 编辑成功，写入日志
                    $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.user_edit'), lang('log.edit_user_info',['name'=>$data['username']]));
                } else {
                    // 否则执行添加操作
                    $data['salt'] = CodeExtend::uuid();
                    $data['password'] = CodeExtend::encryptPassword($data['password'], $data['salt']);
                    $data['id'] = $this->modelSystemUser->add($data);
                    unset($data['password']);
                    unset($data['salt']);
                    // 创建成功，写入日志
                    // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.user_add'), lang('log.add_user_info',['name'=>$data['username'],'password'=>$data['password2']]));
                }
            } catch (\Exception $e) {
                // 更新失败，输出错误日志，并返回错误信息
                // $this->seviceSystem->setLog($e->getCode(), 'error', $e->getMessage(), lang('log.user_save_error', ['message'=> $e->getMessage()]));
                return $this->json($e->getCode(), $e->getMessage());
            }

            // 对用户信息进行处理，以返回给客户端
            $result = $data;
            unset($result['password2']);
            if (empty($data['id'])) $result['salt'] = CodeExtend::md5ShaEncrypt($data['salt']);
            $result['role_list'] = json_decode($data['role_list'], true);
            $result['role_names'] = $this->logicRole->getRolesName($result['role_list']);

            // 返回保存结果和用户信息
            return $this->json(SUCCESS, lang('user.save_user_info_success'), $result);
        });
    }

    /**
     * 更新用户状态
     * @param array $data 包含用户 ID 和用户状态值的数组
     * @return array 包含成功码、成功信息和用户信息的 JSON 对象
     */
    public function stateUser(array $data)
    {
        return $this->tryCatch(function() use ($data){
            // 根据 $data 中的 id 值，更新用户状态为 $data 中的 status 值。
            $this->modelSystemUser->updateById($data['id'], $data);
            // 根据用户状态值，设置日志信息
            $status = $data['status'] == 0 ? lang('log.disabled_user', ['id' => $data['id']]) : lang('log.enabled_user', ['id' => $data['id']]);
            // 更新成功，写入日志
            // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.user_state'), $status);
            // 返回保存结果和用户信息
            return $this->json(SUCCESS, lang('user.update_user_status_success'), $data);
        });
    }

    /**
     * 批量重置用户密码
     * @param  array  $data 待重置用户列表
     * @return array        重置操作结果，成功为批量写入操作结果数组，失败为空数组
     */
    public function resetUser(array $data)
    {
        return $this->tryCatch(function() use ($data){
            // 过滤掉传入的空数据
            $data = array_filter($data, function($v) {
                return !empty($v) || $v === 0 || $v === '0';
            });
            // 获取选中的用户信息
            $info = $this->modelSystemUser->whereIn('id', $data['ids'])->column('id, password, salt');
            // 检查原密码是否正确，如果错误，则返回错误信息
            $validatePassword = !empty($data['password']); // 是否需要验证密码
            foreach ($info as $id => $user) {
                if ($validatePassword && CodeExtend::encryptPassword($data['password'], $user['salt']) !== $user['password']) {
                    return $this->json(STRING_MATCH_ERROR, lang('user.old_password_error'));
                }
                $info[$id]['password'] = CodeExtend::encryptPassword($data['newpassword'], $user['salt']);
            }
            // 批量保存数据
            try {
                $this->modelSystemUser->saveAll($info);
                // 更新成功，写入日志
                // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.reset_password'), lang('log.reset_password_for',['id' => implode(',', $data['ids']),'password'=>$data['newpassword']]));
                return $this->json(SUCCESS, lang('user.reset_password_success'));
            } catch (\Exception $e) {
                // 更新失败，输出错误日志，并返回错误信息
                // $this->seviceSystem->setLog($e->getCode(), 'error', $e->getMessage(), lang('log.user_reset_error', ['message'=> $e->getMessage()]));
                return $this->json($e->getCode(), $e->getMessage());
            }
        });
    }

    /**
     * 以事务方式删除多个用户及其所有子孙用户。
     * @param array $data 待删除用户ID列表
     * @return JsonResponse
     * @throws \think\db\exception\PDOException
     * @throws \Throwable
     */
    public function deleteUser(array $data)
    {
        return $this->tryCatch(function() use ($data) {
            // 删除用户
            $this->modelSystemUser->whereIn('id', $data['ids'])->delete();
            // 删除成功，写入日志
            // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.user_delete'), lang('log.user_delete_for', ['id' => implode(',',$data['ids'])]));
            // 返回删除成功的信息和状态
            return $this->json(SUCCESS, lang('user.delete_user_success'));
        });
    }
}